package xyz.scootaloo.kami.server.model

import xyz.scootaloo.kami.server.standard.currentTimeMillis

/**
 * @author flutterdash@qq.com
 * @since 2022/2/23 11:23
 */

class UploadFileResponse(
    val success: Boolean,
    val message: String,
    val taskId: String,
    val error: UploadExceedLimitReporter?,
    val files: List<ActualUploadFileInfo> = ArrayList()
) {
    companion object {
        fun error(
            msg: String, reporter: UploadExceedLimitReporter
        ) = UploadFileResponse(
            false, msg, "",  reporter
        )
    }
}

/**
 * @property taskId 此上传任务的唯一ID
 * @property files 此上传任务所上传的文件列表
 * @property dbId 此上传任务在数据表中的记录ID
 * @property done 整个上传任务是否完成 (即上传任务中所有的文件都上传完成)
 * @property lastActionTime 最近一次动作的时间 (即最近一次文件块上传的时间)
 * @property hasSaveChanged 当文件改动后, 会将改动保存到数据库, 假如保存了改动, 则为true
 * @property hasChanged 当文件上传进度有更新时, 则为true
 * @property successCount 文件列表中, 已上传完成的文件的数量
 */
class UploadTaskInfo {
    var uploader = 0
    lateinit var taskId: String
    lateinit var uploadPath: String
    lateinit var files: Map<String, ActualUploadFileInfo>
    var dbId: Int = 0
    var done: Boolean = false
    var lastActionTime: Long = 0
    var hasSaveChanged = false
    var hasChanged = false
    var successCount = 0

    companion object {
        fun create(
            uploader: Int, taskId: String, path: String, files: List<ActualUploadFileInfo>
        ): UploadTaskInfo {
            val fileMapper = files.associateBy { it.uploadFilename }
            return UploadTaskInfo().apply {
                this.uploader = uploader
                this.taskId = taskId
                this.uploadPath = path
                this.files = fileMapper
                this.lastActionTime = currentTimeMillis()
            }
        }
    }
}

/**
 * @property uploadFilename 上传时提交的文件名
 * @property realFilename 上传到服务器时, 该文件的实际文件名
 * @property tmpFilename 当该文件尚未上传完成, 使用的临时文件名
 * @property progress 文件上传的进度
 * @property filesize 文件的大小
 * @property chunkedSize 文件分块上传时, 每一块的大小
 * @property chunkCount 按照[chunkedSize]进行分段, [filesize]会分成[chunkCount]块
 * @property successCount 已经上传成功的文件块数量
 * @property done 是否所有的部分都上传完成
 */
class ActualUploadFileInfo {
    lateinit var uploadFilename: String
    lateinit var realFilename: String
    lateinit var tmpFilename: String
    var progress: BooleanArray = booleanArrayOf()
    var filesize: Long = 0
    var chunkedSize: Long = 0
    var chunkCount: Long = 0
    var successCount: Long = 0
    var done = false

    fun updateProgress() {
        progress = BooleanArray(chunkCount.toInt()) { false }
    }
}
